#!/usr/bin/python3
import gc
import os
from openpyxl import load_workbook
from .Base_Plugin import Base_Plugin
from models.Generator_Server_Code.Dictionary import Dictionary_Type, Dictionary_Item
from models.Generator_Server_Code.Entity_Field import Entity_Field
from models.Generator_Server_Code.Entity import Entity
from models.Generator_Server_Code.Model_Base_Query import Model_Base_Query
from models.Generator_Server_Code.Model_Query import Model_Query
from models.Generator_Server_Code.Entity_Page_Params import Entity_Page_Params
from models.Generator_Server_Code.Entity_Update_BO import Entity_Update_BO
from models.Generator_Server_Code.Entity_BO import Entity_BO
from models.Generator_Server_Code.Entity_Base_BO import Entity_Base_BO
from models.Generator_Server_Code.Entity_VO import Entity_VO
from models.Generator_Server_Code.Entity_Base_VO import Entity_Base_VO
from models.Generator_Server_Code.Lookup_Constants import DictionaryConstant
from models.Generator_Server_Code.Cachekey import Cachekey
from models.Generator_Server_Code.Service_Base_Broker import Service_Base_Broker
from models.Generator_Server_Code.Service_Broker import Service_Broker
from models.Generator_Server_Code.Controller import Controller
from models.Generator_Server_Code.Service import Service
from models.Generator_Server_Code.Service_Impl import Service_Impl
from models.Generator_Server_Code._Mapper import Mapper
from models.Generator_Server_Code._Mapper_XML import Mapper_XML


class Generator_Server_Code(Base_Plugin):
    """
    生成服务端代码插件
    """

    def __init__(self, context) -> None:
        super().__init__()
        self.context = context

    def get_lookups(self, _lookup_type, _lookup_item) -> list[Dictionary_Type]:
        lookup_types: list[Dictionary_Type] = []
        for row in _lookup_type.rows:
            if row[0].row < self.project_config["通用开始行"] or row[3].value != "Y":
                continue
            code = row[0].value
            lookup_type = Dictionary_Type(code, row[1].value, list[Dictionary_Item]())
            lookup_types.append(lookup_type)

        for row in _lookup_item.rows:
            if row[0].row < self.project_config["通用开始行"] or row[5].value != "Y":
                continue
            code = row[0].value
            for item in lookup_types:
                if item.code == code:
                    lookup_item = Dictionary_Item(row[1].value, row[2].value)
                    item.lookup_items.append(lookup_item)
                    break
        return lookup_types

    def get_fields(self, entity_name, sheet):
        entity_fields = list()
        _index = 0
        for row in sheet.rows:
            if _index < 3:
                _index += 1
                continue

            if row[1].value is None:
                break

            entity_fields.append(
                Entity_Field(
                    self.context,
                    entity_name,
                    column_name=row[1].value,
                    sql_type=row[2].value,
                    comment=row[6].value,
                    not_null=row[3].value,
                    single_verify=row[7].value,
                    i18n=row[8].value,
                    unique=row[4].value,
                    currency=row[8].value,
                )
            )
        return entity_fields

    def run(self, workspace, source):
        author = self.context["author"]
        package = f"""{self.context["package"]}.{self.context["id"]}"""
        workbook = load_workbook(os.path.join(workspace, source))
        _directory = workbook["目录"]
        _lookup_type = workbook["数据字典组"]
        _lookup_item = workbook["数据字典项"]
        lookups = self.get_lookups(_lookup_type, _lookup_item)

        _target_path = os.path.join(workspace, self.context["code_target"])
        if not os.path.exists(_target_path):
            os.mkdir(_target_path)

        entities = list[Entity]()
        for row in _directory.rows:
            if row[0].row < self.project_config["通用开始行"]:
                continue

            entity = Entity(self.context, author, package, row[1].value, row[2].value)
            entity.add_fields(self.get_fields(entity.name, workbook[row[2].value]))
            entity.save_file(_target_path)
            base_exists = Model_Base_Query(self.context, entity)
            base_exists.save_file(_target_path)
            exists = Model_Query(self.context, entity)
            exists.save_file(_target_path)
            query_info = Entity_Page_Params(self.context, entity)
            query_info.save_file(_target_path)
            updateBo = Entity_Update_BO(self.context, entity)
            updateBo.save_file(_target_path)
            bo = Entity_BO(self.context, entity)
            bo.save_file(_target_path)
            baseBO = Entity_Base_BO(self.context, entity)
            baseBO.save_file(_target_path)
            vo = Entity_VO(self.context, entity)
            vo.save_file(_target_path)
            baseVO = Entity_Base_VO(self.context, entity)
            baseVO.save_file(_target_path)
            lookup_constants = DictionaryConstant(self.context, entity, lookups)
            lookup_constants.save_file(_target_path)
            # base_broker = Service_Base_Broker(self.context, entity)
            # base_broker.save_file(_target_path)
            # broker = Service_Broker(self.context, entity)
            # broker.save_file(_target_path)
            controller = Controller(self.context, entity)
            controller.save_file(_target_path)
            service = Service(self.context, entity)
            service.save_file(_target_path)
            service_impl = Service_Impl(self.context, entity)
            service_impl.save_file(_target_path)
            mapper = Mapper(self.context, entity)
            mapper.save_file(_target_path)
            mapper_xml = Mapper_XML(self.context, entity)
            mapper_xml.save_file(_target_path)
            entities.append(entity)
            self.processed += 1
        cachekey = Cachekey(self.context, entities)
        cachekey.save_file(_target_path)
        self.processed += 1
        del workbook
        gc.collect()
        return source
